package com.wencai.daily.utils;

import com.wencai.daily.Main;
import com.wencai.daily.bean.DailyData;
import com.wencai.daily.bean.FiveMinutesData;
import org.jetbrains.annotations.NotNull;
import com.wencai.util.IOUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author wangpan
 * @date 2023/6/1
 */
public class ReadUtils {

    public static void main(String[] args) throws IOException {
//        List<DailyData> dailyData = readDailyData("D:\\Users\\Administrator\\Desktop\\日线策略\\日线数据2020", "sh.600000_浦发银行.txt");
//        System.out.println(dailyData.stream().filter(item -> item.getPctChg() > 2).collect(Collectors.toList()).size());
        List<FiveMinutesData> list = readFiveMinutesData("D:\\Users\\Administrator\\Desktop\\日线策略\\5分线数据2020", "sh.600008.txt",
                "2020-09-18");
        System.out.println(list);
    }

    public static final Pattern pattern = Pattern.compile("[\\.\\da-zA-z]_?(.*)\\.txt");

    public static List<DailyData> readDailyData(String path, String file) throws IOException {
        Matcher matcher = pattern.matcher(file);
        if (matcher.find()) {
            final String name = matcher.group(1);
            List<String> list = IOUtils.readFromFile(new File(path, file).getPath());
            if (list.isEmpty()) {
                System.out.println(path + file + ";isEmpty;");
                return new ArrayList<>();
            }
            list.remove(0);
            List<DailyData> dailyDataList = list.stream().map(line -> convert(name, line)).collect(Collectors.toList());
            return dailyDataList;
        } else {
            return new ArrayList<>();
        }
    }

    public static DailyData readOneDailyData(String path, String file, String date) throws IOException {
        List<DailyData> dailyData = readDailyData(path, file);
        return dailyData.stream().filter(item -> item.getDate().replace("-", "").equals(date.replace("-", ""))).findFirst().get();
    }

    public static DailyData convert(String name, String line) {
        try {
            String[] str = line.split(",");
            DailyData dailyData = new DailyData(
                    str[0], str[1], name, Double.valueOf(str[2]), Double.valueOf(str[3]),
                    Double.valueOf(str[4]), Double.valueOf(str[5]),
                    Double.valueOf(str[6]), parseDouble(str[7]),
                    parseDouble(str[8]), Integer.valueOf(str[9]),
                    parseDouble(str[10]), parseDouble(str[11]), parseDouble(str[12]),
                    Integer.valueOf(str[13])
            );
            return dailyData;
        } catch (Exception e) {
            throw e;
        }
    }

    @NotNull
    private static Double parseDouble(String str) {
        return Double.valueOf(str.isEmpty() ? "0" : str);
    }


    public static Map<String, List<FiveMinutesData>> readAllFiveMinutesData(String dir, String date) throws IOException {
        File file = new File(dir);
        String[] children = file.list();
        Map<String, List<FiveMinutesData>> map = new HashMap<>();
        for (String str : children) {
            List<String> list = IOUtils.readFromFile(new File(dir, str).getPath());
            list.remove(0);
            String code = str.replace(".txt", "");
            map.put(code, convert(code, list, date));
        }
        return map;
    }

    public static List<FiveMinutesData> readFiveMinutesData(String path, String file, String date) throws IOException {
        Matcher matcher = pattern.matcher(file);
        if (matcher.find()) {
            final String name = matcher.group(1);
            List<String> list = IOUtils.readFromFile(new File(path, file).getPath());
            if (!list.isEmpty()) {
                list.remove(0);
            } else {
                System.out.println("list is Empty, file is:" + file);
            }
            return convert(name, list, date);
        } else {
            return new ArrayList<>();
        }
    }

    public static List<FiveMinutesData> convert(String name, List<String> lines, String date) {
        if (!date.contains("-")) {
            date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
        }
        final String finalDate = date;
        List<String> collect = lines.stream().filter(item -> item.startsWith(finalDate)).collect(Collectors.toList());
        if (collect.isEmpty()) {
            return new ArrayList<>();
        }
        List<FiveMinutesData> list = convertFileToFiveMinutesData(name, collect);
        return list;
    }

    @NotNull
    private static List<FiveMinutesData> convertFileToFiveMinutesData(String name, List<String> collect) {
        List<FiveMinutesData> list = new ArrayList<>();
        for (String line : collect) {
            String[] str = line.split(",");
            FiveMinutesData fiveMinutesData = new FiveMinutesData(
                    str[0], str[1], str[2], name, Double.valueOf(str[3]),
                    Double.valueOf(str[4]), Double.valueOf(str[5]), Double.valueOf(str[6]),
                    Double.valueOf(str[7]), Double.valueOf(str[8]), Integer.valueOf(str[9])
            );
            list.add(fiveMinutesData);
        }
        return list;
    }


    @NotNull
    public static Map<String, List<DailyData>> readAllDailyDatas(String currentYear) throws IOException {
        Map<String, List<DailyData>> dailyDataMap = new TreeMap<>();

        String dailyDataDir = "D:\\Users\\Administrator\\Desktop\\记录\\所有日线数据\\";

        File file = new File(dailyDataDir);
        String[] list = file.list();
        for (String str : list) {
            if (str.endsWith("txt")) {
                List<DailyData> dailyDataList = ReadUtils.readDailyData(dailyDataDir, str).stream().filter(item -> item.getAmount() > 0).collect(Collectors.toList());
                for (int i = 0; i < dailyDataList.size() - 1; i++) {
                    if (i < 9) {
                        continue;
                    }
                    DailyData dailyData = dailyDataList.get(i);
                    double fiveDayAvgAmount = dailyDataList.subList(i - 4, i + 1).stream().mapToDouble(item -> item.getAmount()).sum() / 5;
                    double tenDayAvgAmount = dailyDataList.subList(i - 9, i + 1).stream().mapToDouble(item -> item.getAmount()).sum() / 10;
                    double yesterdayAmount = dailyDataList.get(i - 1).getAmount();
                    double yesterdayPctChg = dailyDataList.get(i - 1).getPctChg();
                    dailyData.setFiveDayAvgAmount(fiveDayAvgAmount);
                    dailyData.setTenDayAvgAmount(tenDayAvgAmount);
                    dailyData.setYesterdayAmount(yesterdayAmount);
                    dailyData.setFiveDayAmountRate(dailyData.getAmount() / fiveDayAvgAmount);
                    dailyData.setTenDayAmountRate(dailyData.getAmount() / tenDayAvgAmount);
                    dailyData.setYesterdayAmountRate(dailyData.getAmount() / yesterdayAmount);

                    double fiveDayAvgPrice = dailyDataList.subList(i - 4, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 5;
                    double tenDayAvgPrice = dailyDataList.subList(i - 9, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 10;
                    double threeDayAvgPrice = dailyDataList.subList(i - 2, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 3;

                    dailyData.setFiveDayAvgPrice(fiveDayAvgPrice);
                    dailyData.setTenDayAvgPrice(tenDayAvgPrice);
                    dailyData.setThreeDayAvgPrice(threeDayAvgPrice);
                    dailyData.setYesterdayPctChg(yesterdayPctChg);

                    double tenDayMaxPctChg = dailyDataList.subList(i - 9, i).stream().mapToDouble(item -> item.getPctChg()).max().getAsDouble();
                    dailyData.setTenDayMaxPctChg(tenDayMaxPctChg);

                }
                dailyDataList = dailyDataList.stream().filter(Main::filterStock).collect(Collectors.toList());

                for (DailyData dailyData : dailyDataList) {
                    String date = dailyData.getDate();
                    if (dailyDataMap.containsKey(date)) {
                        List<DailyData> dailyData1 = dailyDataMap.get(date);
                        dailyData1.add(dailyData);
                    } else {
                        List<DailyData> dailyData1 = new ArrayList<>();
                        dailyData1.add(dailyData);
                        dailyDataMap.put(date, dailyData1);
                    }
                }

            }
        }
        return dailyDataMap;
    }

    @NotNull
    public static String getDailyDataDir(String currentYear) {
        return "D:\\Users\\Administrator\\Desktop\\日线策略\\日线数据" + currentYear + "\\";
    }


    @NotNull
    public static Map<String, List<DailyData>> readAllDailyDatas() throws IOException {
        Map<String, List<DailyData>> dailyDataMap = new TreeMap<>();

        String dailyDataDir = "D:\\Users\\Administrator\\Desktop\\记录\\所有日线数据\\";

        File file = new File(dailyDataDir);
        String[] list = file.list();
        for (String str : list) {
            if (str.endsWith("txt")) {
                List<DailyData> dailyDataList = ReadUtils.readDailyData(dailyDataDir, str).stream().filter(item -> item.getAmount() > 0).filter(item -> item.getIsSt() == 0).collect(Collectors.toList());
                for (int i = 0; i < dailyDataList.size() - 1; i++) {
                    if (i < 9) {
                        continue;
                    }
                    DailyData dailyData = dailyDataList.get(i);
                    double fiveDayAvgAmount = dailyDataList.subList(i - 4, i + 1).stream().mapToDouble(item -> item.getAmount()).sum() / 5;
                    double tenDayAvgAmount = dailyDataList.subList(i - 9, i + 1).stream().mapToDouble(item -> item.getAmount()).sum() / 10;
                    double yesterdayAmount = dailyDataList.get(i - 1).getAmount();
                    dailyData.setFiveDayAvgAmount(fiveDayAvgAmount);
                    dailyData.setTenDayAvgAmount(tenDayAvgAmount);
                    dailyData.setYesterdayAmount(yesterdayAmount);
                    dailyData.setFiveDayAmountRate(dailyData.getAmount() / fiveDayAvgAmount);
                    dailyData.setTenDayAmountRate(dailyData.getAmount() / tenDayAvgAmount);
                    dailyData.setYesterdayAmountRate(dailyData.getAmount() / yesterdayAmount);

                    double fiveDayAvgPrice = dailyDataList.subList(i - 4, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 5;
                    double tenDayAvgPrice = dailyDataList.subList(i - 9, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 10;
                    double threeDayAvgPrice = dailyDataList.subList(i - 2, i + 1).stream().mapToDouble(item -> item.getClose()).sum() / 3;

                    dailyData.setFiveDayAvgPrice(fiveDayAvgPrice);
                    dailyData.setTenDayAvgPrice(tenDayAvgPrice);
                    dailyData.setThreeDayAvgPrice(threeDayAvgPrice);
                }
//                dailyDataList = dailyDataList.stream().filter(Main::filterStock).collect(Collectors.toList());
                dailyDataMap.put(str.replace(".txt", ""), dailyDataList);
            }
        }
        return dailyDataMap;
    }
}
